﻿using Sasa.QualityTools.CodeAnalysis.Core.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sasa.QualityTools.CodeAnalysis.Common;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.ViewModels
{
    public abstract class CodeAnalyzerViewModelBase<TModel> : ViewModelBase, ICodeAnalyzerViewModel
        where TModel : ICodeAnalyzer, new()
    {
        private string target;

        private CodeAnalysisStatus status;

        private string message;


        public string Target
        {
            get
            {
                return target;
            }
            set
            {
                target = value;
                OnPropertyChanged("Target");
            }
        }

        public CodeAnalysisStatus Status
        {
            get
            {
                return status;
            }
            protected set
            {
                status = value;
                OnPropertyChanged("Status");
            }
        }

        public string Message
        {
            get
            {
                return message;
            }
            protected set
            {
                message = value;
                OnPropertyChanged("Message");
            }
        }

        public string CommandPath
        {
            get
            {
                return Model.CommandPath;
            }
            set
            {
                Model.CommandPath = value;
                OnPropertyChanged("CommandPath");
            }
        }

        public string CommandOption
        {
            get
            {
                return Model.CommandOption;
            }
            set
            {
                Model.CommandOption = value;
                OnPropertyChanged("CommandOption");
            }
        }

        public ICollection<string> ReferenceAssemblyPaths
        {
            get
            {
                return Model.ReferenceAssemblyPaths;
            }
        }

        protected TModel Model { get; private set; }


        protected CodeAnalyzerViewModelBase()
        {
            Model = new TModel();
        }


        protected abstract void PerformCodeAnalysisCore();

        protected abstract void LoadCodeAnalysisReportCore();

        protected abstract void NotifyCodeAnalysisPerformed();

        protected abstract void NotifyCodeAnalysisCompleted();

        protected abstract void NotifyCodeAnalysisFailed(Exception ex);

        public void PerformCodeAnalysis()
        {
            NotifyCodeAnalysisPerformed();

            try
            {
                PerformCodeAnalysisCore();
                NotifyCodeAnalysisCompleted();
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Failed to perform code analysis.");
                NotifyCodeAnalysisFailed(ex);
            }
        }

        public void LoadCodeAnalysisReport()
        {
            try
            {
                LoadCodeAnalysisReportCore();
                NotifyCodeAnalysisCompleted();
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Failed to load code analysis report.");
                NotifyCodeAnalysisFailed(ex);
            }
        }

        public void MarkAsCompletedOnBuildTime()
        {
            Status = CodeAnalysisStatus.CompletedOnBuildTime;
            Message = "This project has already analyzed on build time.";
        }

        public void SkipPeforming(string reason)
        {
            Status = CodeAnalysisStatus.Skip;
            Message = reason;
        }
    }
}
